﻿using System;
using System.Windows.Forms;
using System.Drawing;
using SDK;
using System.Collections.Generic;
using System.Linq;
using YF.NLOG;
using ThermoGroupSample.PLC;

/// <summary>
/// 该例子将演示最多两个热像仪同时播放的情况，每个热像仪包含一路红外+一路内置可见光（内置可见光选配）
/// </summary>
namespace ThermoGroupSample
{
    public partial class FormMain : Form
    {
        public CameraInstance[] mCameras;
        private GroupSDK.STREAM_TYPE mStreamType = GroupSDK.STREAM_TYPE.STREAM_TEMPERATURE;

        #region 新增
        public static string path = Convert.ToString(System.AppDomain.CurrentDomain.BaseDirectory) + @"ini\point.ini";
        public ExtensionMethods extension = new ExtensionMethods();
        public double setTemp = 0;//测量温差值
        public double setNgPercent = 0;//测量异常上线百分比
        public double setTempRage = 0;//温度范围（用于判断产品是否为A/B面接反）
        private int initStart = 0;
        private bool connectPlc = false;
        #endregion

        // One camera maybe contains a infrared sensor and a visible sensor
        public struct CameraInstance
        {
            public MagDevice device;
            public FormInfrared infrared;
            public FormVisible visible;
        }
        /// <summary>
        /// 窗体对象实例
        /// </summary>
        private static FormMain _instance;
        public static FormMain Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new FormMain();
                }
                return _instance;
            }
        }
        public FormMain()
        {
            InitializeComponent();

            comboBoxStream.SelectedIndex = 0;

            // construct two camera instance
            mCameras = new CameraInstance[2];

            // initialize camera form
            for (int i = 0; i < mCameras.Length; i++)
            {
                mCameras[i].device = new MagDevice();

                mCameras[i].infrared = new FormInfrared();
                mCameras[i].infrared.TopLevel = false;
                mCameras[i].infrared.Dock = DockStyle.Fill;
                mCameras[i].infrared.bindDevice(mCameras[i].device);

                mCameras[i].visible = new FormVisible();
                mCameras[i].visible.TopLevel = false;
                mCameras[i].visible.Dock = DockStyle.Fill;
                mCameras[i].visible.bindDevice(mCameras[i].device);

                mCameras[i].visible.bindInfrared(mCameras[i].infrared);
            }

            // camera0
            panel1.Controls.Add(mCameras[0].infrared);
            mCameras[0].infrared.Show();
            updateButtons();

            comboBoxIndex.SelectedIndex = 0;
        }


        private void FormMain_Paint(object sender, PaintEventArgs e)
        {
            // Draw rectangle to screen.
            e.Graphics.FillRectangle(new SolidBrush(Color.White), 2, 6, 812, 610);
        }

        private bool play(int i, string ip)
        {
            try
            {
                if (ip.Equals(""))
                {
                    return false;
                }

                Cursor = Cursors.WaitCursor;
                bool ret1 = mCameras[i].infrared.play(ip, mStreamType);
                bool ret2 = mCameras[i].visible.play(ip);
                Cursor = Cursors.Arrow;

                updateButtons();
                return ret1 || ret2;
            }
            catch (Exception ex)
            {
                LoggerHelper._log.Error($"【热像仪打开异常】：{ex.Message}", ex);
                MessageBox.Show($"热像仪打开异常：{ex.Message}");
                return false;
            }

        }

        private void stop(int i)
        {
            // visible stop before infrared always a good idea.
            // beacuse channel will be invalid after infrared stop
            mCameras[i].visible.stop();
            mCameras[i].infrared.stop();
            updateButtons();
        }

        private void saveDDT(int i)
        {
            mCameras[i].infrared.saveDDT();
        }

        private void saveBMP(int i)
        {
            mCameras[i].infrared.saveBMP();
            mCameras[i].visible.saveBMP();
        }

        private void loadDDT(int i)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "DDT Files(*.ddt)|*.ddt|All Files(*.*)|*.*";
            if (dlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            mCameras[i].infrared.stop();
            mCameras[i].visible.stop();
            mCameras[i].infrared.loadDDT(dlg.FileName);
            updateButtons();
        }

        private void mgsRecording(int i, int para)
        {
            if (para == 0)
            {
                mCameras[i].infrared.stopMgsRecording();
            }
            else
            {
                mCameras[i].infrared.startMgsRecording();
            }
            updateButtons();
        }


        private void loadMgs(int i)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "DDT Files(*.mgs)|*.mgs|All Files(*.*)|*.*";
            if (dlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            mCameras[i].infrared.loadMGS(dlg.FileName);
            updateButtons();
        }

        private void uploadRoiToCamera(int i)
        {
            mCameras[i].infrared.uploadRoiToCamera();
        }

        //////////////////////////////Button click event///////////////////////////////

        private void updateButtons()
        {
            int index = 0;
            buttonPlay1.Enabled = !mCameras[index].infrared.isPlaying();
            buttonStop1.Enabled = mCameras[index].infrared.isPlaying();
            //buttonSaveDDT1.Enabled = mCameras[index].infrared.isPlaying() && mStreamType == GroupSDK.STREAM_TYPE.STREAM_TEMPERATURE;
            //buttonSaveBMP1.Enabled = mCameras[index].infrared.isPlaying();
            buttonLoadDDT1.Enabled = !mCameras[index].infrared.isPlaying();
            //buttonSaveMgsStart1.Enabled = mCameras[index].infrared.isPlaying() && !mCameras[index].infrared.isMgsRecording() &&
            //    mStreamType == GroupSDK.STREAM_TYPE.STREAM_TEMPERATURE;
            //buttonSaveMgsStop1.Enabled = mCameras[index].infrared.isPlaying() && mCameras[index].infrared.isMgsRecording() &&
            //    mStreamType == GroupSDK.STREAM_TYPE.STREAM_TEMPERATURE;
            //buttonLoadMGS1.Enabled = !mCameras[index].infrared.isPlaying();

            index++;


            buttonUploadRoi.Enabled = mCameras[0].infrared.isPlaying() || mCameras[1].infrared.isPlaying();
            button1.Enabled = mCameras[0].infrared.isPlaying();
        }

        private void buttonPlay1_Click(object sender, EventArgs e)
        {
            var playres = play(0, textBoxIp1.Text);
            if (playres)
            {
                UIUpdate.UpdateControl(Instance.richTextBox1, "热像仪开启成功", Color.Blue);
                PlcInit();
            }
            else
            {
                UIUpdate.UpdateControl(Instance.richTextBox1, "相机开启失败，请检查热像仪状态", Color.Red);
            }
        }

        private void buttonStop1_Click(object sender, EventArgs e)
        {
            stop(0);
        }

        private void buttonSaveDDT1_Click(object sender, EventArgs e)
        {
            saveDDT(0);
        }

        private void buttonSaveBMP1_Click(object sender, EventArgs e)
        {
            saveBMP(0);
        }

        private void buttonLoadDDT1_Click(object sender, EventArgs e)
        {
            loadDDT(0);
        }


        private void checkBoxMouseTemp_CheckedChanged(object sender, EventArgs e)
        {
            mCameras[0].infrared.enableMouseTemp(checkBoxMouseTemp.CheckState == CheckState.Checked);
            mCameras[1].infrared.enableMouseTemp(checkBoxMouseTemp.CheckState == CheckState.Checked);
        }

        private void checkBoxRectTemp_CheckedChanged(object sender, EventArgs e)
        {
            mCameras[0].infrared.enableRectTemp(checkBoxRectTemp.CheckState == CheckState.Checked);
            mCameras[1].infrared.enableRectTemp(checkBoxRectTemp.CheckState == CheckState.Checked);
        }

        private void comboBoxStream_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (comboBoxStream.SelectedIndex)
            {
                case 0:
                    mStreamType = GroupSDK.STREAM_TYPE.STREAM_TEMPERATURE;
                    break;
                case 1:
                    mStreamType = GroupSDK.STREAM_TYPE.STREAM_VIDEO;
                    break;
                case 2:
                    mStreamType = GroupSDK.STREAM_TYPE.STREAM_HYBRID;
                    break;
            }
        }

        private void buttonSaveMgsStart1_Click(object sender, EventArgs e)
        {
            mgsRecording(0, 1);
        }

        private void buttonSaveMgsStop1_Click(object sender, EventArgs e)
        {
            mgsRecording(0, 0);
        }

        private void buttonSaveMgsStart2_Click(object sender, EventArgs e)
        {
            mgsRecording(1, 1);
        }

        private void buttonSaveMgsStop2_Click(object sender, EventArgs e)
        {
            mgsRecording(1, 0);
        }

        private void buttonLoadMGS1_Click(object sender, EventArgs e)
        {
            loadMgs(0);
        }

        private void buttonLoadMGS2_Click(object sender, EventArgs e)
        {
            loadMgs(1);
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            stop(0);
            stop(1);
        }

        private void buttonUploadRoi_Click(object sender, EventArgs e)
        {
            uploadRoiToCamera(0);
            uploadRoiToCamera(1);
        }

        private async void button1_Click(object sender, EventArgs e)
        {

            var res = await mCameras[0].infrared.GetRectPoinTemp();
            int ngCount = res.Count(it => it == true);
            MessageBox.Show("手动测试完成");

            //Test
            //var listTemp = await mCameras[0].infrared.GetRectPoinTemp2();
            //Dictionary<int, int> frequencyMap = new Dictionary<int, int>();
            //foreach (int item in listTemp)
            //{
            //    if (frequencyMap.ContainsKey(item))
            //    {
            //        frequencyMap[item]++;
            //    }
            //    else
            //    {
            //        frequencyMap[item] = 1;
            //    }
            //}
            //int mostFrequentItem = frequencyMap.OrderByDescending(x => x.Value).First().Key;
            //int maxCount = frequencyMap.OrderByDescending(x => x.Key).First().Key;
            //int minCount = frequencyMap.OrderBy(x => x.Key).First().Key;
        }

        private void comboBoxIndex_SelectedIndexChanged(object sender, EventArgs e)
        {
            string areaNo = "point" + comboBoxIndex.SelectedIndex.ToString();
            string startX = extension.INIRead(areaNo, "startX", FormMain.path);
            string startY = extension.INIRead(areaNo, "startY", FormMain.path);
            string endX = extension.INIRead(areaNo, "endX", FormMain.path);
            string endY = extension.INIRead(areaNo, "endY", FormMain.path);
            textBoxStartX.Text = startX;
            textBoxEndX.Text = endX;
            textBoxStartY.Text = startY;
            textBoxEndY.Text = endY;
        }

        private void buttonSET_Click(object sender, EventArgs e)
        {

            //int startX = mCameras[0].infrared.nTempRect.X;
            //int rectW = mCameras[0].infrared.nTempRect.Width;
            //int startY = mCameras[0].infrared.nTempRect.Y;
            //int rectH = mCameras[0].infrared.nTempRect.Height;
            //textBoxStartX.Text = startX.ToString();
            //textBoxEndX.Text = (startX + rectW).ToString();
            //textBoxStartY.Text = startY.ToString();
            //textBoxEndY.Text = (startY + rectH).ToString();

            //保存坐标信息到本地
            if (textBoxStartX.Text == "" && textBoxStartY.Text == "" && textBoxEndX.Text == "" && textBoxEndY.Text == "")
            {
                MessageBox.Show("设置失败，ROI区域未选择！");
                return;
            }
            string iIndex = comboBoxIndex.SelectedIndex.ToString();
            SavePos(iIndex, 1, textBoxStartX.Text, textBoxStartY.Text, textBoxEndX.Text, textBoxEndY.Text);
        }

        private void roiCheck_CheckedChanged(object sender, EventArgs e)
        {
            if (roiCheck.Checked)
            {
                mCameras[0].infrared.isRoi = true;
            }
            else
            {
                mCameras[0].infrared.isRoi = false;
            }
        }

        #region 扩展
        private void SavePos(string indexP, int type = 0, string startX = "0", string startY = "0", string endX = "0", string endY = "0")
        {
            try
            {
                string section = "point" + indexP;
                extension.INIWrite(section, "index", indexP, path);
                extension.INIWrite(section, "startX", startX, path);
                extension.INIWrite(section, "startY", startY, path);
                extension.INIWrite(section, "endX", endX, path);
                extension.INIWrite(section, "endY", endY, path);
                MessageBox.Show($"【{comboBoxIndex.Text}】ROI设置成功！");
                textBoxStartX.Text = startX;
                textBoxEndX.Text = endX;
                textBoxStartY.Text = startY;
                textBoxEndY.Text = endY;
                if (type == 0)
                {//删除
                    mCameras[0].infrared.rectangles.RemoveAt(0);
                }
                mCameras[0].infrared.Invalidate();
            }
            catch (Exception ex)
            {
                MessageBox.Show("ROI设置异常：" + ex.Message);
                LoggerHelper._log.Error("【ROI设置异常】", ex);
                MessageBox.Show($"ROI设置异常：{ex.Message}");
            }
        }
        #endregion

        private void buttonDelete_Click(object sender, EventArgs e)
        {
            try
            {
                SavePos(comboBoxIndex.SelectedIndex.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show("ROI删除异常：" + ex.Message);
                LoggerHelper._log.Error("ROI删除异常！" + ex.Message, ex);
            }
        }

        private void btn_SetCheck_Click(object sender, EventArgs e)
        {
            try
            {
                string tempSet = txt_TempSet.Text.Trim();
                string percent = txt_P.Text.Trim();
                string tempRange = txt_TempRange.Text.Trim();
                if (tempSet != "" && percent != "" && tempRange != "")
                {
                    setTemp = double.Parse(tempSet);
                    setNgPercent = double.Parse(percent) / 100;
                    setTempRage = double.Parse(tempRange);
                    extension.INIWrite("setTempCheck", "tempVal", tempSet, path);
                    extension.INIWrite("setTempCheck", "ngPercent", percent, path);
                    extension.INIWrite("setTempCheck", "tempRange", tempRange, path);
                    MessageBox.Show("设置成功！");
                }
                else
                {
                    MessageBox.Show("测量温差信息不能为空！");
                }
            }
            catch (Exception ex)
            {
                LoggerHelper._log.Error("【测量温差信息设置异常】", ex);
                MessageBox.Show($"测量温差信息设置异常：{ex.Message}");
            }
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            string ngPercent = extension.INIRead("setTempCheck", "ngPercent", path);
            setTemp = double.Parse(extension.INIRead("setTempCheck", "tempVal", path));
            setNgPercent = double.Parse(ngPercent) / 100;
            setTempRage = double.Parse(extension.INIRead("setTempCheck", "tempRange", path));
            txt_TempSet.Text = setTemp.ToString();
            txt_P.Text = ngPercent;
            txt_TempRange.Text = setTempRage.ToString();
            //play(0, textBoxIp1.Text);
        }

        private void checkBoxRoi_CheckedChanged(object sender, EventArgs e)
        {
            if (!checkBoxRoi.Checked)
            {
                mCameras[0].infrared.MouseClick -= new System.Windows.Forms.MouseEventHandler(mCameras[0].infrared.FormInfrared_MouseClick);
                mCameras[0].infrared.MouseDown -= new System.Windows.Forms.MouseEventHandler(mCameras[0].infrared.FormInfrared_MouseDown);
                mCameras[0].infrared.MouseUp -= new System.Windows.Forms.MouseEventHandler(mCameras[0].infrared.FormInfrared_MouseUp);
            }
            else
            {
                mCameras[0].infrared.MouseClick += new System.Windows.Forms.MouseEventHandler(mCameras[0].infrared.FormInfrared_MouseClick);
                mCameras[0].infrared.MouseDown += new System.Windows.Forms.MouseEventHandler(mCameras[0].infrared.FormInfrared_MouseDown);
                mCameras[0].infrared.MouseUp += new System.Windows.Forms.MouseEventHandler(mCameras[0].infrared.FormInfrared_MouseUp);
            }
        }

        public void PlcInit()
        {
            //PLC初始化
            initStart += 1;
            connectPlc = PlcOperation.Instance.ConnectPlc();
            if (initStart <= 2 && !connectPlc)
            {
                PlcInit();
            }
            if (connectPlc)
            {
                PlcOperation.Instance.Start(); // 启动读取PLC变量的线程
            }
            else
            {
                MessageBox.Show("PLC连接失败，请检查接口网络后重启客户端！", "PLC连接初始化");
                this.Dispose();
                this.Close();
                System.Environment.Exit(0);
                return;
            }
        }

    }
}
